#pragma once

#include <d3dx9math.h>

class Quaternion : public D3DXQUATERNION
{
public:
	Quaternion() : D3DXQUATERNION() {}
	Quaternion(D3DXQUATERNION &q) : D3DXQUATERNION(q) {}

	// Modifiers
	inline void Normalize() {D3DXQuaternionNormalize(this, this);}
	inline void Slerp(const Quaternion& begin, const Quaternion& end, float coeff)
	{
		// Performs spherical linear interpolation between begin & end
		// NOTE: set coeff between 0.f - 1.f
		D3DXQuaternionSlerp(this, &begin, &end, coeff);
	}

	// Accessors
	inline void GetAxisAngle(Vector3& axis, float& angle) const
	{
		D3DXQuaternionToAxisAngle(this, &axis, &angle);
	}

	// Initializers
	inline void BuildRotYawPitchRoll(const float yawRadians, const float pitchRadians, const float rollRadians)
	{
		D3DXQuaternionRotationYawPitchRoll(this, yawRadians, pitchRadians, rollRadians);
	}

	inline void BuildAxisAngle(const Vector3& axis, const float radians)
	{
		D3DXQuaternionRotationAxis(this, &axis, radians);
	}

	void Build(const class Mat44& mat);

	static const Quaternion g_identity;
};

inline Quaternion operator*(const Quaternion& a, const Quaternion& b)
{
	// For rotations, this is exactly like concatenating matrices
	// The new quat represents rot A followed by rot B.
	Quaternion out;
	D3DXQuaternionMultiply(&out, &a, &b);
	return out;
}